#include "../include/Engine.hpp"
#include "../include/Data.hpp"
#include "../include/TexturedNode.hpp"
#include "../include/PrimitiveNode.hpp"
#include "../include/FontNode.hpp"
#include "../include/Timer.hpp"
#include "../include/Utils.hpp"
#include "../include/ParticleEngine.hpp"
#include "../include/SoundEngine.hpp"
#include "../include/PostProcessor.hpp"

using namespace klas;

#include <iostream>
using namespace std;

Engine* engine = NULL;
Data* data = new Data();
Scene* scene = new Scene(Vector2<Real>(2000, 2000), 1000);

int main()
{
  engine = new Engine(Vector2<Real>(500, 500));
	engine->setCaption("klas");
	engine->setScene(scene);
	
	/* Post Processor */
  PostProcessor* postProcessor = new PostProcessor(Vector2<iReal>(500, 500));
  //engine->setPostProcessor(postProcessor);
	
  cout << "loading image" << endl;
	data->load("image", "basic.tga", Data::TEXTURE);

  SoundEngine* soundEngine = new SoundEngine();
  data->load("music", "music.mp3", Data::MUSIC);

  soundEngine->addTrack(data->get("music"));
  soundEngine->addTrack(data->get("music"));
  soundEngine->playTracklist();
  soundEngine->pauseMusic();
  soundEngine->resumeMusic();
  soundEngine->skipTrack();
  
  cout << "creating a node" << endl;
	/* Textured Node */
	TexturedNode* texNode = new TexturedNode(data->get("image"));
	cout << "here" << endl;
	texNode->setPos(Vector2<Real>(400, 400));	
	cout << "setting pos" << endl;
	//texNode->setRot(45);
	texNode->setScale(30.0);
	scene->add(texNode, Scene::DEEP_COPY);
	cout << "adding to scene" << endl;
	texNode->setRot(33);
	texNode->setScale(3.0);
	scene->add(texNode, Scene::DEEP_COPY);

	texNode->setRot(0);
	texNode->setScale(1.0);
	scene->add(texNode);
	
	
	/* Circle node */	
	PrimitiveNode* circleNode = new PrimitiveNode(Vector2<Real>(250, 250), 15.0, Color(.35, .2, .32, .9), 30);
	circleNode->setScale(2.0);
	scene->add(circleNode, Scene::DEEP_COPY);
	
	circleNode->changeColor(Color(0, 255, 0, .6));
	circleNode->setScale(1.0);
	scene->add(circleNode, Scene::DEEP_COPY);

	circleNode->changeColor(Color(0, 0, 255, .6));
	circleNode->setScale(5.0);
	scene->add(circleNode, Scene::RENDER_BACK);

		
	/* Rectangle node */
	PrimitiveNode* rectangleNode = new PrimitiveNode(Vector2<Real>(15, 130), Rectangle<Real>(Vector2<Real>(0, 0), Vector2<Real>(32, 32)), Color(.35, .2, .32, .3));
	scene->add(rectangleNode);
	
	PrimitiveNode* rN = new PrimitiveNode(Vector2<Real>(15, 130), Rectangle<Real>(Vector2<Real>(0, 0), Vector2<Real>(32, 32)), Color(.62, .34, .32, .3));
	rN->setRot(45);
	rN->setScale(3.0);
	scene->add(rN, Scene::RENDER_BACK);
	
	
	/* Triangle node */
	Point ptA(Vector2<Real>(0, 5), Color(255, 0, 0)),
				ptB(Vector2<Real>(0, -5), Color(0, 255, 0)),
				ptC(Vector2<Real>(5, 5), Color(0, 0, 255));
				
	PrimitiveNode* triangleNode = new PrimitiveNode(Vector2<Real>(20, 0), ptA, ptB, ptC);
	triangleNode->setScale(6);
	scene->add(triangleNode, Scene::DEEP_COPY);
	
	triangleNode->setScale(9);
	triangleNode->setRot(325);
	scene->add(triangleNode);

		
	/* Manual rectangle node */
	Point pt1(Vector2<Real>(-5, 5), Color(255, 0, 0, 20)),
				pt2(Vector2<Real>(5, 5), Color(0, 255, 0, 20)),
				pt3(Vector2<Real>(5, -5), Color(0, 0, 255, 20)),
				pt4(Vector2<Real>(-5, -5), Color(255, 255, 0, 20));
	
	PrimitiveNode* manualNode = new PrimitiveNode();
	manualNode->addPoint(pt4);
	manualNode->addPoint(pt3);
	manualNode->addPoint(pt2);
	manualNode->addPoint(pt1);
	manualNode->setPos(Vector2<Real>(80, 80));
	manualNode->setScale(10);
	scene->add(manualNode, Scene::DEEP_COPY);
	
	//manualNode->setRot(135);
	manualNode->setScale(20);
	scene->add(manualNode, Scene::RENDER_BACK);
	
	/* End of Primitive declarations */
	
	engine->getCamPtr()->translate(Vector2<Real>(-100, -100));
		
	
	/* Fonts */
  cout << "loading font" << endl;
	data->load("font", "HappyPhantom.ttf");
  FontNode* txt = new FontNode();
  txt->setFont(data->get("font"));
	txt->setPos(Vector2<Real>(10, 10));
	txt->setBaseColor(Color(255, 255, 0));
	txt->setScale(1.0);
	scene->add(txt);

	/* Particles */
	ParticleEngine* particleEngine = new ParticleEngine();
	engine->setParticleEngine(particleEngine);
	

  cout << "loading particle" << endl;
  data->load("particle", "particle3.png");

	
	ParticleEmitter* emitter = new ParticleEmitter(Vector2<Real>(400, 400), Vector2<Real>(400, 400), 300);

	emitter->setTexture(data->get("particle"));
	emitter->setVelocities(Vector2<Real>(-70, -70), Vector2<Real>(70, 70));
	emitter->setColors(Color(255, 0, 0, 255), Color(0, 0, 255, 0));
  emitter->setScale(.8, .8, .8, .8);
	particleEngine->addEmitter(emitter);
	

	ParticleEmitter* emitter2 = new ParticleEmitter(Vector2<Real>(200, 200), Vector2<Real>(200, 200), 300);
	emitter2->setCreationRate(15, 40);
	emitter2->setTexture(data->get("particle"));
	emitter2->setVelocities(Vector2<Real>(100, 100), Vector2<Real>(160, 160));
	emitter2->setColors(Color(0, 255, 0, 255), Color(255, 255, 0, 80));
  emitter2->setScale(.8, .8, .8, .8);
	particleEngine->addEmitter(emitter2);
	
	ParticleEmitter* emitter3 = new ParticleEmitter(Vector2<Real>(600, 200), Vector2<Real>(600, 200), 500);
	emitter3->setCreationRate(30, 35);
	emitter3->setTexture(data->get("particle"));
	emitter3->setVelocities(Vector2<Real>(-400, -500), Vector2<Real>(400, -1000));
  emitter3->setScale(.6, .8, .6, .8);
  emitter3->setColors(Color(255, 185, 15, 200), Color(255, 0, 0, 0));
	emitter3->setLifeSpan(.8, 1);
	particleEngine->addEmitter(emitter3);
	
	/* end particles */
	
  SDL_Event event;
  
	Timer timer;
	Real fps = 0.0;
	Real prev, dt;
	prev = timer.getSeconds();
	Vector2<Real> mouse;
	bool run = true;
	
	cout << "running" << endl;
	while(run)
	{
		dt = timer.getSeconds() - prev;
		prev = timer.getSeconds();
		
    Real utilsFPS = Utils::getFPS();
    if(!Utils::isEqual(fps, utilsFPS))
		{
      string a = "FPS: ";
            // b = "\nParticles: ",
            // c = Utils::getString(emitter->getParticleCount() + emitter2->getParticleCount() + emitter3->getParticleCount());
      txt->setText(a + Utils::getString(utilsFPS));// + b + c);
      fps = utilsFPS;
		}
		

		//emitter->emitParticles();
		//emitter2->emitParticles();

		while(SDL_PollEvent(&event))
		{
      mouse.x = event.button.x + engine->getCamPtr()->getRect().x;
			mouse.y = event.button.y + engine->getCamPtr()->getRect().y;
			
			if(event.type == SDL_QUIT)
				run = false;
			
			Uint8 *keys = SDL_GetKeyState(NULL);	
			if(keys[SDLK_p])
				for(int i = 0; i < 100000; ++i)
				{cout << "a" << endl;}
		}
		


		

		//emitter3->setPos(mouse);
		circleNode->setPos(mouse);

		particleEngine->update(dt);
		engine->render();
		
		

		
	}
  cout << "killing scene" << endl;
	scene->kill();
  cout << "deleting engine" << endl;
	delete(engine);	
  cout << "deleting scene" << endl;
	delete(scene);
  cout << "deleting particle engine" << endl;
	delete(particleEngine);
	cout << "deleting sound engine" << endl;
	delete(soundEngine);
	cout << "deleting post processor" << endl;
	delete(postProcessor);
  cout << "deleting data" << endl;
	delete(data);
}
